#include "server.h"
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <functional>
#include <thread>
#include "../utils/string.h"
#include "../utils/json.h"

// 构造函数
HttpServer::HttpServer(int port, AssetManager *manager)
    : port(port), serverSocket(-1), running(false), assetManager(manager)
{
    registerRoutes();
}

// 析构函数
HttpServer::~HttpServer()
{
    stop();
}

// 初始化服务器套接字
void HttpServer::initSocket()
{
    // 创建TCP套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0)
    {
        throw std::runtime_error("Failed to create socket");
    }

    // 设置套接字选项，允许端口重用
    int opt = 1;
    if (setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        close(serverSocket);
        throw std::runtime_error("Failed to set socket options");
    }

    // 绑定地址和端口
    sockaddr_in serverAddr;
    std::memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(port);

    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    {
        close(serverSocket);
        throw std::runtime_error("Failed to bind socket");
    }

    // 开始监听连接
    if (listen(serverSocket, 5) < 0)
    {
        close(serverSocket);
        throw std::runtime_error("Failed to listen on socket");
    }
}

// 解析HTTP请求
Request HttpServer::parseRequest(const std::string &data)
{
    Request req;
    std::istringstream stream(data);
    std::string line;

    // 解析请求行
    if (std::getline(stream, line))
    {
        line = StringUtils::trim(line);
        std::istringstream requestLine(line);
        std::string method, path, version;
        requestLine >> method >> path >> version;
        req.method = method;
        req.path = path;
        req.version = version;
    }

    // 解析请求头
    while (std::getline(stream, line) && line != "\r")
    {
        line = StringUtils::trim(line);
        size_t colonPos = line.find(':');
        if (colonPos != std::string::npos)
        {
            std::string key = StringUtils::trim(line.substr(0, colonPos));
            std::string value = StringUtils::trim(line.substr(colonPos + 1));
            req.headers[key] = value;
        }
    }

    // 解析请求体
    if (req.headers.find("Content-Length") != req.headers.end())
    {
        try
        {
            size_t contentLength = std::stoul(req.headers["Content-Length"]);
            if (contentLength > 0)
            {
                // 移动到请求体开始位置
                std::streampos currentPos = stream.tellg();
                if (currentPos != std::streampos(-1))
                {
                    // 读取请求体
                    char *buffer = new char[contentLength + 1];
                    stream.read(buffer, contentLength);
                    buffer[contentLength] = '\0';
                    req.body = std::string(buffer);
                    delete[] buffer;
                }
            }
        }
        catch (...)
        {
            // 忽略Content-Length解析错误
        }
    }

    return req;
}

// 注册所有路由处理函数
void HttpServer::registerRoutes()
{
    routes["GET /assets"] = std::bind(&HttpServer::handleGetAssets, this, std::placeholders::_1, std::placeholders::_2);
    routes["GET /assets/"] = std::bind(&HttpServer::handleGetAssetById, this, std::placeholders::_1, std::placeholders::_2);
    routes["POST /assets"] = std::bind(&HttpServer::handlePostAsset, this, std::placeholders::_1, std::placeholders::_2);
    routes["PUT /assets/"] = std::bind(&HttpServer::handlePutAsset, this, std::placeholders::_1, std::placeholders::_2);
    routes["DELETE /assets/"] = std::bind(&HttpServer::handleDeleteAsset, this, std::placeholders::_1, std::placeholders::_2);
}

// 处理客户端连接
void HttpServer::handleClient(int clientSocket)
{
    char buffer[4096];
    ssize_t bytesRead = read(clientSocket, buffer, sizeof(buffer) - 1);

    if (bytesRead > 0)
    {
        buffer[bytesRead] = '\0';
        std::string requestData(buffer);

        // 解析请求
        Request req = parseRequest(requestData);
        Response res;

        // 查找并执行对应的路由处理函数
        std::string routeKey = req.method + " " + req.path;

        // 检查是否是带ID的资产请求
        size_t assetsPos = req.path.find("/assets/");
        if (assetsPos == 0 && req.path.length() > 8)
        {
            routeKey = req.method + " /assets/";
        }

        auto it = routes.find(routeKey);
        if (it != routes.end())
        {
            it->second(req, res);
        }
        else
        {
            handleNotFound(req, res);
        }

        // 发送响应
        std::string responseStr = res.toString();
        send(clientSocket, responseStr.c_str(), responseStr.length(), 0);
    }

    close(clientSocket);
}

// 服务器主循环
void HttpServer::run()
{
    while (running)
    {
        sockaddr_in clientAddr;
        socklen_t clientAddrLen = sizeof(clientAddr);
        int clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);

        if (clientSocket >= 0 && running)
        {
            // 为每个客户端连接创建新线程处理
            std::thread clientThread(&HttpServer::handleClient, this, clientSocket);
            clientThread.detach();
        }
    }
}

// 启动服务器
void HttpServer::start()
{
    if (!running)
    {
        initSocket();
        running = true;
        mainThread = std::make_unique<std::thread>(&HttpServer::run, this);
    }
}

// 停止服务器
void HttpServer::stop()
{
    if (running)
    {
        running = false;
        if (serverSocket >= 0)
        {
            close(serverSocket);
            serverSocket = -1;
        }
        if (mainThread && mainThread->joinable())
        {
            mainThread->join();
        }
    }
}

// 处理获取所有资产请求
void HttpServer::handleGetAssets(const Request &req, Response &res)
{
    std::vector<Asset> assets = assetManager->getAllAssets();
    res.statusCode = 200;
    res.statusMessage = "OK";
    res.headers["Content-Type"] = "application/json";
    res.body = JsonUtils::serializeAssets(assets);
}

// 处理获取特定资产请求
void HttpServer::handleGetAssetById(const Request &req, Response &res)
{
    // 提取资产ID
    size_t idPos = req.path.find_last_of("/");
    if (idPos == std::string::npos || idPos == req.path.length() - 1)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID\"}";
        return;
    }

    std::string idStr = req.path.substr(idPos + 1);
    try
    {
        int id = std::stoi(idStr);
        Asset asset;
        if (assetManager->getAssetById(id, asset))
        {
            res.statusCode = 200;
            res.statusMessage = "OK";
            res.headers["Content-Type"] = "application/json";
            res.body = JsonUtils::serializeAsset(asset);
        }
        else
        {
            res.statusCode = 404;
            res.statusMessage = "Not Found";
            res.body = "{\"error\": \"Asset not found\"}";
        }
    }
    catch (...)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID format\"}";
    }
}

// 处理创建资产请求
void HttpServer::handlePostAsset(const Request &req, Response &res)
{
    if (req.body.empty())
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Empty request body\"}";
        return;
    }

    Asset asset = JsonUtils::parseAsset(req.body);
    if (asset.name.empty())
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset data\"}";
        return;
    }

    int newId = assetManager->addAsset(asset);
    asset.id = newId;

    res.statusCode = 201;
    res.statusMessage = "Created";
    res.headers["Content-Type"] = "application/json";
    res.headers["Location"] = "/assets/" + std::to_string(newId);
    res.body = JsonUtils::serializeAsset(asset);
}

// 处理更新资产请求
void HttpServer::handlePutAsset(const Request &req, Response &res)
{
    // 提取资产ID
    size_t idPos = req.path.find_last_of("/");
    if (idPos == std::string::npos || idPos == req.path.length() - 1)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID\"}";
        return;
    }

    std::string idStr = req.path.substr(idPos + 1);
    try
    {
        int id = std::stoi(idStr);

        if (req.body.empty())
        {
            res.statusCode = 400;
            res.statusMessage = "Bad Request";
            res.body = "{\"error\": \"Empty request body\"}";
            return;
        }

        Asset asset = JsonUtils::parseAsset(req.body);
        if (asset.name.empty())
        {
            res.statusCode = 400;
            res.statusMessage = "Bad Request";
            res.body = "{\"error\": \"Invalid asset data\"}";
            return;
        }

        asset.id = id;
        if (assetManager->updateAsset(asset))
        {
            res.statusCode = 200;
            res.statusMessage = "OK";
            res.headers["Content-Type"] = "application/json";
            res.body = JsonUtils::serializeAsset(asset);
        }
        else
        {
            res.statusCode = 404;
            res.statusMessage = "Not Found";
            res.body = "{\"error\": \"Asset not found\"}";
        }
    }
    catch (...)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID format\"}";
    }
}

// 处理删除资产请求
void HttpServer::handleDeleteAsset(const Request &req, Response &res)
{
    // 提取资产ID
    size_t idPos = req.path.find_last_of("/");
    if (idPos == std::string::npos || idPos == req.path.length() - 1)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID\"}";
        return;
    }

    std::string idStr = req.path.substr(idPos + 1);
    try
    {
        int id = std::stoi(idStr);
        if (assetManager->deleteAsset(id))
        {
            res.statusCode = 204;
            res.statusMessage = "No Content";
        }
        else
        {
            res.statusCode = 404;
            res.statusMessage = "Not Found";
            res.body = "{\"error\": \"Asset not found\"}";
        }
    }
    catch (...)
    {
        res.statusCode = 400;
        res.statusMessage = "Bad Request";
        res.body = "{\"error\": \"Invalid asset ID format\"}";
    }
}

// 处理未找到的路由
void HttpServer::handleNotFound(const Request &req, Response &res)
{
    res.statusCode = 404;
    res.statusMessage = "Not Found";
    res.body = "{\"error\": \"Resource not found\"}";
}
